<?php

namespace RedMVC\Feed;
use RedMVC;

/**
 * Reader class
 *
 * @category    RedMVC
 * @package     Feed 
 * @author      Jan Fischer, bitWorking <info@bitworking.de>
 */
class Reader{

    public static function getFeed($url, $timeout, $method = RedMVC\File::REMOTE_DATA_METHOD_CURL){
        $xml        = RedMVC\File::getRemoteData($url, $timeout, $method);
        $xmlArray   = self::xmlToArray($xml);
        $feed       = self::xmlArrayToFeed($xmlArray);
        return $feed;
    }
    
    public static function xmlToArray($xml, $getAttributes = 1){
        if(trim($xml) == ''){
            return array();
        }
        if(!function_exists('xml_parser_create')){
            return array();
        }

        $parser = xml_parser_create(); 
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); 
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, true); 
        xml_parse_into_struct($parser, $xml, $xmlValues);
        xml_parser_free($parser);
        
        if(!$xmlValues){
            return array();
        }

        $xmlArray   = array();        
        $current    = &$xmlArray;

        foreach($xmlValues as $data){
            unset($attributes, $value);
            extract($data);            
            $result = ''; 
            if($getAttributes){
                $result = array(); 
                if(isset($value)){
                    $result['value'] = $value;
                }
                if(isset($attributes)){
                    foreach($attributes as $attr => $val) { 
                        $result['attr'][$attr] = $val;
                    }
                }
            } 
            else if(isset($value)){
                $result = $value;
            }  
            if($type == "open"){
                $parent[$level-1] = &$current;                
                if(!is_array($current) or (!in_array($tag, array_keys($current)))){
                    $current[$tag] = $result; 
                    $current = &$current[$tag];
                } 
                else{
                    if(isset($current[$tag][0])){
                        array_push($current[$tag], $result); 
                    }
                    else{ 
                        $current[$tag] = array($current[$tag], $result);
                    } 
                    $last = count($current[$tag]) - 1; 
                    $current = &$current[$tag][$last]; 
                }
            } 
            else if($type == "complete"){
                if(!isset($current[$tag])){
                    $current[$tag] = $result;
                } 
                else{
                    if((is_array($current[$tag]) && $getAttributes == 0)
                        || (isset($current[$tag][0]) 
                        && is_array($current[$tag][0]) and $getAttributes == 1)){
                        array_push($current[$tag], $result);
                    }
                    else{
                        $current[$tag] = array($current[$tag], $result);
                    } 
                }
            }
            else if($type == 'close'){
                $current = &$parent[$level-1]; 
            } 
        }
        return $xmlArray; 
    }
    
    public static function xmlArrayToFeed($xmlArray){
        if(count($xmlArray) == 0){
            return new RedMVC\Feed();
        }		
		// atom
		if(isset($xmlArray['feed']['entry'])){
			if(count($xmlArray['feed']['entry']) > 0){
				return self::atomToFeed($xmlArray);
			}
		}		
		// rss 0.9
		else if(isset($xmlArray['rdf:RDF']['item'])){
			if(count($xmlArray['rdf:RDF']['item']) > 0){
				return self::rss09ToFeed($xmlArray);
			}
		}
        // rss 2.0
		else if(isset($xmlArray['rss']['channel']['item'])){
			if(count($xmlArray['rss']['channel']['item']) > 0){
				return self::rss20ToFeed($xmlArray);
			}
		}	
		return new RedMVC\Feed();
	}
	
	public static function atomToFeed($xmlArray){		
		$feed = new RedMVC\Feed();

		if(isset($xmlArray['feed']['title']['value'])){
            $feed->title = $xmlArray['feed']['title']['value'];
		}
		if(isset($xmlArray['feed']['link'][0]['attr']['href'])){
            $feed->link = $xmlArray['feed']['link'][0]['attr']['href'];
		}
		if(isset($xmlArray['feed']['subtitle']['value'])){
            $feed->description = $xmlArray['feed']['subtitle']['value'];
		}
        if(isset($xmlArray['feed']['author']['name']['value'])){
            $feed->author = $xmlArray['feed']['author']['name']['value'];
		}
        if(isset($xmlArray['feed']['updated']['value'])){
            $feed->date = strtotime($xmlArray['feed']['updated']['value']);
		}
		
        foreach($xmlArray['feed']['entry'] as $news){
			$title 		= $news['title']['value'];
			$link 		= $news['link']['attr']['href'];			
			$updated 	= strtotime($news['updated']['value']);			
			$summary	= $news['summary']['value'];

            $entry = new RedMVC\Feed\Entry();            
            $entry->title   = $title;
            $entry->date    = $updated;
			$entry->summary = $summary;
			$entry->link    = $link;
			
			$feed->addEntry($entry);
		}
		return $feed;
	}
	
	public static function rss09ToFeed($xmlArray){
		$feed = new RedMVC\Feed();

		if(isset($xmlArray['rdf:RDF']['channel']['title']['value'])){
            $feed->title = $xmlArray['rdf:RDF']['channel']['title']['value'];
		}
		if(isset($xmlArray['rdf:RDF']['channel']['link']['value'])){
            $feed->link = $xmlArray['rdf:RDF']['channel']['link']['value'];
		}
		if(isset($xmlArray['rdf:RDF']['channel']['description']['value'])){
            $feed->description = $xmlArray['rdf:RDF']['channel']['description']['value'];
		}
		
		foreach($xmlArray['rdf:RDF']['item'] as $news){
			$title 		= $news['title']['value'];
			$link 		= $news['link']['value'];
			$summary	= $news['description']['value'];
			
            $entry = new RedMVC\Feed\Entry();            
            $entry->title   = $title;            
			$entry->summary = $summary;
			$entry->link    = $link;			
			
			$feed->addEntry($entry);
		}
		return $feed;
	}
	
	public static function rss20ToFeed($xmlArray){		
		$feed = new RedMVC\Feed();
		
		if(isset($xmlArray['rss']['channel']['title']['value'])){
            $feed->title = $xmlArray['rss']['channel']['title']['value'];
		}
		if(isset($xmlArray['rss']['channel']['link']['value'])){
            $feed->link = $xmlArray['rss']['channel']['link']['value'];
		}
		if(isset($xmlArray['rss']['channel']['description']['value'])){
            $feed->description = $xmlArray['rss']['channel']['description']['value'];
		}

        foreach($xmlArray['rss']['channel']['item'] as $news){
			$title 		= $news['title']['value'];
			$link 		= $news['link']['value'];            
			$date 		= '';
			if(isset($news['pubDate']['value'])){			    
				$date = strtotime($news['pubDate']['value']);				
			}
			$imgUrl = '';
			if(isset($news['media:content']['attr']['type']) && 
                ($news['media:content']['attr']['type']=='image/jpeg' 
                || $news['media:content']['attr']['type']=='image/gif' 
                || $news['media:content']['attr']['type']=='image/png')){
                $imgUrl = $news['media:content']['attr']['url'];                
			}
			else if(isset($news['enclosure']['attr']['type']) && 
                    ($news['enclosure']['attr']['type']=='image/jpeg' 
                    || $news['enclosure']['attr']['type']=='image/gif' 
                    || $news['enclosure']['attr']['type']=='image/png')){
			    $imgUrl = $news['enclosure']['attr']['url'];                
			}
			else if(isset($news['content:encoded']['value'])){
			     $imgUrl = self::_getSrcFromPic($news['content:encoded']['value']);
            }
            
            $summary = '';
            if(isset($news['description']['value'])){
                $summary = $news['description']['value'];
            }
            else if(isset($news['content:encoded']['value'])){
                $summary = $news['content:encoded']['value'];
            }
	
            $entry = new RedMVC\Feed\Entry();            
            $entry->title   = $title;
            $entry->date    = $date;
			$entry->summary = $summary;
			$entry->link    = $link;
			$entry->image   = $imgUrl;
			
			$feed->addEntry($entry);
		}
		return $feed;
	}

	protected static function _getSrcFromPic($titel){
		$pattern  = "/((@import\s+[\"'`]([\w:?=@&\/#._;-]+)[\"'`];)|";
		$pattern .= "(:\s*url\s*\([\s\"'`]*([\w:?=@&\/#._;-]+)";
		$pattern .= "([\s\"'`]*\))|<[^>]*\s+(src|href|url)\=[\s\"'`]*";
		$pattern .= "([\w:?=@&\/#._;-]+)[\s\"'`]*[^>]*>))/i";		
		preg_match_all ($pattern, $titel, $matches);
		$m = (is_array($matches)) ? $matches : false;
		$links = self::_xArrayMerge($m[3], self::_xArrayMerge($m[5], $m[8]));
		foreach($links as $link){
		    if(self::_isPic($link)){
		        return $link;
		    }
		}
		return '';
	}
	
	protected static function _xArrayMerge($arr1, $arr2){
		$arr = Array();
        for($i=0;$i<count($arr1);$i++) {
		   $arr[$i] = ($arr1[$i] == '') ? $arr2[$i] : $arr1[$i];
		}
		return $arr;
	}
	
	protected static function _isPic($url){
        $array  = explode('.',$url);
        $ext    = strtolower($array[count($array)-1]);
        if($ext == 'jpg' || $ext == 'gif' || $ext == 'png'){
            return true;
        }
        return false;
	}


}